﻿using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Reflection;

namespace Blog.Middleware
{
		
	public class RequestLoggingMiddleware
	{
		public readonly RequestDelegate _next;
		public readonly ILogger<RequestLoggingMiddleware> _logger;

		public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger)
		{
			_next = next;
			_logger = logger;
		}

		public async Task InvokeAsync(HttpContext context) {

			if (context.User.Identity.IsAuthenticated)
			{
				var userId = context.User.FindFirst("Id")?.Value;
				var userName = context.User?.Identity?.Name;
				var ip = context.Connection.RemoteIpAddress?.ToString();
				var city = "";
				if (ip == "::1") {
					ip = "127.0.0.1";
					city = "本地地址无法获取城市信息";
				}
				else {
					city = await GetCityByIp(ip);
				}
				 ; // 这里可以使用IP定位服务获取城市
				var operationTime = DateTime.UtcNow;

				Assembly assembly = Assembly.GetExecutingAssembly();
				string assemblyName  = assembly.GetName().Name;
				var module = assemblyName; // 模块名可以根据需要自行定义

				var path = context.Request.Path;
				var method = context.Request.Method;

				var routeData = context.GetRouteData();

				var controllerName =  routeData.Values["controller"]?.ToString();
				var className = controllerName;

				_logger.LogInformation("Request Info: UserId: {UserId}, UserName: {UserName}, IP: {IP}, City: {City}, OperationTime: {OperationTime}, Module: {Module}, Path: {Path}, Method: {Method}, ClassName: {ClassName}",
			   userId, userName, ip, city, operationTime, module, path, method, className);
			}
			else
			{
				_logger.LogInformation("User is not authenticated.");
			}

			// 调用下一个中间件
			await _next(context);
		}

		private async Task<string> GetCityByIp(string ip)
		{
			using var httpClient = new HttpClient();
			var response = await httpClient.GetAsync($"https://ipinfo.io/{ip}/json");

			if (response.IsSuccessStatusCode)
			{
				var data = await response.Content.ReadFromJsonAsync<IpInfo>();
				return data?.City ?? "Unknown";
			}

			return "Unknown";
		}

		// 创建一个用于解析 JSON 响应的类
		private class IpInfo
		{
			public string City { get; set; }
		}


	}
}
